﻿using System;
using System.Runtime.InteropServices;
using DirectShowLib;
using MediaFoundation;
using MediaFoundation.EVR;
using MediaFoundation.Misc;
using DirectShowLib.Utils;

namespace MediaPlayer.Renderers
{
    public class EVR : Basic
    {
        new public IMFVideoDisplayControl Control { get; internal set; }

        public EVR(IntPtr handle)
            : base(handle)
        {
            this.filter = (IBaseFilter)new EnhancedVideoRenderer();

            Player.Graph.AddFilter(this.filter, "EVR");


            ///DsGuid ffdshowVid = new DsGuid("{04FE9017-F873-410E-871E-AB91661A4EF7}");
            // IBaseFilter f = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(ffdshowVid));

            // IBaseFilter ffdshowVid = NativeMethods.GetObject(@"Filters\ffdshow.ax", System.Type.GetTypeFromCLSID(new DsGuid("{04FE9017-F873-410E-871E-AB91661A4EF7}")));
            // //var ffdshowVid = NativeMethods.LoadFilterFromDll(@"Filters\ffdshow.ax", new Guid("{04FE9017-F873-410E-871E-AB91661A4EF7}"));
            // //IBaseFilter f = ffdshowVid as IBaseFilter;
            // Player.Graph.AddFilter(ffdshowVid, "ffdshow Video Decoder");

            //IBaseFilter ffdshowAudio = NativeMethods.GetObject(@"Filters\ffdshow.ax", System.Type.GetTypeFromCLSID(new DsGuid("{0F40E1E5-4F79-4988-B1A9-CC98794E6B55}")));
            //Player.Graph.AddFilter(ffdshowAudio, "ffdshow Audio Decoder");



            //FilterGraphTools.AddFilterFromClsid(Player.Graph.Builder, new Guid("{93A22E7A-5091-45EF-BA61-6DA26156A5D0}"), "DirectVobSub");

            //IBaseFilter directVobSubBase = FilterGraphTools.FindFilterByName(Player.Graph.Builder, "DirectVobSub");
            //IDirectVobSub vobSub = directVobSubBase as IDirectVobSub;

            //FilterGraphTools.ShowFilterPropertyPage(directVobSubBase, handle);


            object o;
            IMFGetService getService = (IMFGetService)this.filter;
            getService.GetService(MFServices.MR_VIDEO_RENDER_SERVICE, typeof(IMFVideoDisplayControl).GUID, out o);

            try
            {
                this.Control = (IMFVideoDisplayControl)o;
            }
            catch
            {
                Marshal.ReleaseComObject(o);
                throw;
            }

            this.Control.SetVideoWindow(this.handle);
            this.Control.SetAspectRatioMode(MFVideoAspectRatioMode.None);

            IEVRFilterConfig filterConfig = (IEVRFilterConfig)this.filter;
            filterConfig.SetNumberOfStreams(1);
        }

        override public void SetVideoPosition(MFVideoNormalizedRect src, DsRect dst)
        {
            this.Control.SetVideoPosition(src, new MFRect(dst));
        }

        override protected void Dispose(Boolean freeObjects)
        {
            try
            {
                if (!freeObjects) return;

                lock (this)
                {
                    Player.Graph.RemoveFilter(this.filter);
                    Marshal.ReleaseComObject(this.filter);
                    this.filter = null;

                    this.Control = null;
                }
            }
            finally
            {
                GC.Collect();
            }
        }

        override public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~EVR()
        {
            try
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
            finally
            {
                base.Dispose();
            }
        }
    }
}
